package cc.mrbird.febs.common.utils;

import javax.servlet.http.HttpServletRequest;

/**
 * IP地址工具类
 * 用于获取HTTP请求的真实IP地址
 * 支持多级代理和反向代理场景下的IP地址获取
 * 
 * @author MrBird
 */
public class IPUtil {

	/**
	 * 未知IP地址标识
	 * 当无法获取真实IP地址时返回此值
	 */
	private static final String UNKNOWN = "unknown";

	/**
	 * 私有构造函数，防止实例化
	 */
	protected IPUtil() {
	}

	/**
	 * 获取请求的真实IP地址
	 * 按照以下顺序尝试获取IP地址：
	 * 1. 从X-Forwarded-For头获取
	 * 2. 从Proxy-Client-IP头获取
	 * 3. 从WL-Proxy-Client-IP头获取
	 * 4. 从request.getRemoteAddr()获取
	 * 
	 * 如果使用了Nginx等反向代理软件，不能直接通过request.getRemoteAddr()获取IP地址
	 * 如果使用了多级反向代理，X-Forwarded-For的值会是一串IP地址，取第一个非unknown的有效IP
	 * 
	 * @param request HTTP请求对象
	 * @return 真实IP地址，如果是IPv6的本地地址则返回127.0.0.1
	 */
	public static String getIpAddr(HttpServletRequest request) {
		// 从X-Forwarded-For获取IP
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
			// 从Proxy-Client-IP获取IP
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
			// 从WL-Proxy-Client-IP获取IP
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
			// 从request.getRemoteAddr()获取IP
			ip = request.getRemoteAddr();
		}
		// 如果是IPv6的本地地址，返回127.0.0.1
		return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
	}

}
